<?php
namespace app\admin\controller;

use app\BaseController;
use app\common\model\AdminIpsModel;
use app\common\model\AdminRoleModel;
use app\common\model\AdminUserModel;
use app\common\model\AdminUserLogModel;
use app\common\model\AdminMenuModel;
use app\common\model\CommonModel;

/**
 * Common-控制器
 * @author 贺强
 * @time   2019-06-01 10:16:25
 */
class Common extends BaseController
{
    protected $admin = null;

    /**
     * 初始化函数
     * @author 贺强
     * @time   2019-03-24 09:48:02
     */
    public function initialize()
    {
        if (empty(cookie('_roy')) || cookie('_roy') !== md5('roy@admin$' . date('Ymd'))) {
            exit('Permission denied.');
        }
        $debug = $_COOKIE['debug'] ?? ($_GET['debug'] ?? '');
        $admin = $this->is_login(0);
        if ($admin && !empty($admin['id'])) {
            // 判断是否启用ip限制
            $is_ip = AdminMenuModel::getFieldValue('is_hide', ['identity' => 'admin_ips'], 'debug', 0) ? 0 : 1;
            if ($is_ip) {
                // 判断当前登录的管理员是否有ip限制
                $is_ip = AdminUserModel::getFieldValue('is_ip', ['id' => $admin['id']], 'debug', 0);
                if ($is_ip) {
                    $ip = $this->request->ip();
                    // 登录IP是否在白名单
                    $count = AdminIpsModel::getCount(['ip' => $ip], '', 'debug', 0);
                    $action = $this->request->get('action');
                    if (!$count && empty($action)) {
                        $is_ajax = $this->request->isAjax();
                        if ($is_ajax) {
                            return ['code' => 40, 'message' => '您无权访问'];
                        }
                        $this->error('您无权访问', url('/login/index?action=logout'));
                    }
                }
            }
        }
        // 不需要验证的方法
        $no_valid_action = config('app.NO_VERIFY');
        if ($debug === 'no_valid_action') {
            print_r($no_valid_action);
            exit;
        }
        // 当前访问的方法
        $class = strtolower($this->request->controller());
        $action = strtolower($this->request->action());
        if ($debug === 'class_action') {
            var_dump($class, $action);
            exit;
        }
        if (!empty($no_valid_action[$class]) && ($no_valid_action[$class] === '*' || in_array($action, $no_valid_action[$class]))) {
            $this->admin = $this->is_login(0);
        } else {
            $identity = $class . '_' . $action;
            $admin = $this->is_valid($identity);
            $this->admin = $admin;
        }
        return $admin;
    }

    /**
     * 判断用户是否登录
     * @author 贺强
     * @time   2023/2/15 16:52
     * @param int $is_url 是否需跳转
     * @return array|false|mixed
     */
    protected function is_login($is_url = 1)
    {
        $admin_id = session('admin');
        $action = $this->request->get('action');
        if (empty($admin_id) && empty($action)) {
            if ($this->request->isAjax()) {
                return ['code' => 45, 'message' => '登录超时，请重新登录'];
            }
            if ($is_url === 1) {
                $this->error('登录超时，请重新登录', url('/login/index'));
            } else {
                return false;
            }
        }
        $admin = [];
        if (!empty($admin_id)) {
            $admin = AdminUserModel::getModel(['id' => $admin_id], true, '', 0);
            $menus = AdminRoleModel::getFieldValue('menus', ['id' => $admin['role_id']]);
            $menus = explode(',', $menus);
            // 赋值拥有权限的菜单
            $admin['roles'] = $menus;
            unset($admin['password']);
        }
        return $admin;
    }

    /**
     * 判断登录用户是否有权限
     * @author 贺强
     * @date   2018-08-31
     * @param string $identity 操作/访问的方法
     * @return array|false|mixed
     */
    public function is_valid(string $identity)
    {
        $admin = $this->is_login();
        if (empty($admin) || !empty($admin['code'])) {
            return $admin;
        }
        $is_ajax = $this->request->isAjax();
        $acts = config('app.ACTIONS');
        $data = $this->request->post();
        // 如果是超级管理员不加权限限制
        if ($admin['username'] === 'admin') {
            // 记录操作日志
            if (!empty($acts[$identity]) && ($this->request->isPost() || $this->request->isAjax())) {
                $log = [
                    'admin_id' => $admin['id'],
                    'name' => $admin['name'],
                    'username' => $admin['username'],
                    'login_time' => $admin['login_time'],
                    'login_ip' => $admin['login_ip'],
                    'action' => $identity,
                    'log' => $acts[$identity],
                ];
                if (!empty($data)) {
                    if ($identity === 'doc_editarticle') {
                        unset($data['content']);
                    }
                    $log['data'] = json_encode($data);
                }
                AdminUserLogModel::add($log);
            }
            return $admin;
        }
        $model = AdminUserModel::getModel([['id', '=', $admin['id']]], ['status'], '', 0);
        if (empty($model) || $model['status'] === 4) {
            if ($is_ajax) {
                return ['code' => 40, 'message' => '您的账号已被禁用'];
            }
            $this->error('您的账号已被禁用', url('/login/index?action=logout'));
        }
        // 判断登录账号是否有权限
        if (empty($identity)) {
            if ($is_ajax) {
                return ['code' => 41, 'message' => '您无权访问或操作'];
            }
            $this->error('您无权访问或操作1');
        }
        if (strrpos($identity, '\\') !== false) {
            $identity = substr($identity, strrpos($identity, '\\') + 1);
        }
        $menu = AdminMenuModel::getModel(['identity' => $identity], 'id');
        if (empty($menu)) {
            if ($is_ajax) {
                return ['code' => 42, 'message' => '您无权访问或操作'];
            }
            $this->error('您无权访问或操作2');
        }
        if ($admin['roles'][0] !== '*' && !in_array($menu['id'], $admin['roles'])) {
            if ($is_ajax) {
                return ['code' => 43, 'message' => '您无权访问或操作'];
            }
            if ($identity === 'index_index_v1') {
                return false;
            }
            $this->error('您无权访问或操作3');
        }
        // 记录操作日志
        if (!empty($acts[$identity]) && ($this->request->isPost() || $this->request->isAjax())) {
            $log = [
                'admin_id' => $admin['id'],
                'name' => $admin['name'],
                'username' => $admin['username'],
                'login_time' => $admin['login_time'],
                'login_ip' => $admin['login_ip'],
                'action' => $identity,
                'log' => $acts[$identity],
            ];
            if (!empty($data)) {
                $log['data'] = json_encode($data);
            }
            AdminUserLogModel::add($log);
        }
        return $admin;
    }

    /**
     * 获取可能添加自定义字段的表
     * @author 贺强
     * @time   2023/8/20 9:27
     * @return array
     */
    public function GetCustomFieldTables() : array
    {
        $database = env('database.database', '');
        $prefix = env('database.prefix', '');
        $tableArr = CommonModel::query("SELECT t.TABLE_NAME,t.TABLE_COMMENT FROM information_schema.`TABLES` t WHERE t.TABLE_SCHEMA='$database' AND t.TABLE_NAME NOT LIKE '{$prefix}user_log_%'");
        $tables = [];
        $customTables = config('app.params.custom_field_tables') ?? [];
        if (!empty($customTables)) {
            foreach ($tableArr as $table) {
                if (in_array($table['TABLE_NAME'], $customTables)) {
                    $tables[] = $table;
                }
            }
        }
        return $tables;
    }
}
